home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
bit
/
src
/
forms
/
FORMS
/
objects.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
17KB
|
587 lines
/*
* objects.c
*
* This file is part of the basis of the Forms Library
*
* It contains all basic routines that deal with objects, like making
* them, changing them, drawing them, and sending events to them.
*
* Written by Mark Overmars
*
* Version 2.2 b
* Date: Jun 18, 1993
*/
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "gl/gl.h"
#include "gl/device.h"
#include <malloc.h>
#include "forms.h"
/*-----------------------------------------------------------------------
Creation routines
-----------------------------------------------------------------------*/
FL_FORM *fl_make_form(float w,float h)
/* Creates an empty form. NOT FOR USER. */
{
FL_FORM *form;
form = (FL_FORM *) fl_malloc(sizeof(FL_FORM));
form->w = w; form->h = h;
form->window = -1;
form->deactivated = 1;
form->visible = 0;
form->frozen = 0;
form->form_call_back = NULL;
form->focusobj = NULL;
form->first = NULL;
form->last = NULL;
form->doublebuf = fl_doublebuf;
form->hotx = form->hoty = -1;
return form;
}
FL_OBJECT *fl_make_object(int objclass,int type,float x,float y,
float w,float h, const char *label,FL_HANDLEPTR handle)
/* Creates an object, NOT FOR USER. */
{
FL_OBJECT *ob;
ob = (FL_OBJECT *) fl_malloc(sizeof(FL_OBJECT));
ob->objclass = objclass;
ob->type = type;
ob->boxtype = FL_NO_BOX;
ob->x = x; ob->y = y; ob->w = w; ob->h = h;
ob->label = (char *) fl_malloc(strlen(label)+1);
strcpy(ob->label,label);
ob->handle = handle;
ob->align = FL_ALIGN_CENTER;
ob->lcol = 0;
ob->lsize = FL_NORMAL_FONT;
ob->lstyle = FL_NORMAL_STYLE;
ob->shortcut = (char *) fl_malloc(1);
ob->shortcut[0] = '\0';
ob->pushed = 0;
ob->focus = 0;
ob->belowmouse = 0;
ob->input = 0;
ob->wantall = 0;
ob->active = 1;
ob->visible = 1;
ob->radio = 0;
ob->automatic = 0;
ob->object_call_back = NULL;
ob->spec = NULL;
ob->next = NULL;
ob->prev = NULL;
ob->form = NULL;
return ob;
}
void fl_free_object(FL_OBJECT *obj)
/* Frees the memory used by an object. */
{
/* check whether ok to free it */
if (obj == NULL)
{ fl_error("fl_free_object","Trying to free NULL object."); return;}
if (obj->form != NULL)
{ fl_error("fl_free_object","Freeing non-deleted object."); fl_delete_object(obj);}
/* free object */
if (obj->label != NULL) free(obj->label);
if (obj->shortcut != NULL) free(obj->shortcut);
fl_handle_object(obj, FL_FREEMEM, 0.0, 0.0, 0);
free(obj);
}
void fl_free_form(FL_FORM *form)
/* Frees the memory used by an form, together with all its objects. */
{
FL_OBJECT *current, *next;
/* check whether ok to free */
if (form == NULL)
{ fl_error("fl_free_form","Trying to free NULL form."); return;}
if (form->visible)
{ fl_error("fl_free_form","Freeing visible form."); fl_hide_form(form);}
/* free the objects */
for(next = form->first; next != NULL; )
{
current = next;
next = current->next;
if (current->label != NULL) free(current->label);
if (current->shortcut != NULL) free(current->shortcut);
fl_handle_object(current, FL_FREEMEM, 0.0, 0.0, 0);
free(current);
}
/* free the form structure */
free(form);
}
void fl_add_object(FL_FORM *form, FL_OBJECT *obj)
/* Adds an object to the form. */
{
/* Checking for correct behaviour. */
if (obj == NULL)
{ fl_error("fl_add_object","Trying to add NULL object."); return;}
if (form == NULL)
{ fl_error("fl_add_object","Trying to add object to NULL form."); return;}
obj->prev = obj->next = NULL;
if (form->first == NULL)
form->first = form->last = obj;
else
{
obj->prev = form->last;
form->last->next = obj;
form->last = obj;
}
obj->form = form;
if (obj->input && form->focusobj == NULL) fl_set_object_focus(form,obj);
fl_redraw_object(obj);
}
void fl_insert_object(FL_OBJECT *obj, FL_OBJECT *before)
/* Insert object obj before object before. */
{
FL_FORM *form;
/* Checking for correct behaviour. */
if (obj == NULL)
{ fl_error("fl_insert_object","Trying to insert NULL object."); return;}
if (before == NULL)
{ fl_error("fl_insert_object","Trying to insert before NULL object."); return;}
if (before->form == NULL)
{ fl_error("fl_insert_object","Trying to insert object to NULL form."); return;}
form = before->form;
obj->next = before;
if (before == form->first)
{ form->first = obj; obj->prev = NULL; }
else
{ obj->prev = before->prev; obj->prev->next = obj;}
before->prev = obj;
obj->form = form;
if (obj->input && form->focusobj == NULL) fl_set_object_focus(form,obj);
fl_redraw_form(form);
}
void fl_delete_object(FL_OBJECT *obj)
/* Deletes an object from its form. */
{
FL_FORM *form;
if (obj == NULL)
{ fl_error("fl_delete_object","Trying to delete NULL object."); return;}
if (obj->form == NULL)
{ fl_error("fl_delete_object","Trying to delete from NULL form."); return;}
form = obj->form;
if (obj->focus) fl_set_object_focus(form,NULL);
obj->form = NULL;
if (obj->prev != NULL)
obj->prev->next = obj->next;
else
form->first = obj->next;
if (obj->next != NULL)
obj->next->prev = obj->prev;
else
form->last = obj->prev;
if (form->focusobj == NULL)
fl_set_object_focus(form,fl_find_first(form,FL_FIND_INPUT,0.,0.));
fl_redraw_form(form);
}
/*-----------------------------------------------------------------------
Setting Attributes.
-----------------------------------------------------------------------*/
void fl_set_object_boxtype(FL_OBJECT *ob,int boxtype)
/* Sets the boxtype of the object */
{
if (ob == NULL)
{ fl_error("fl_set_object_boxtype","Setting boxtype of NULL object."); return;}
ob->boxtype = boxtype;
fl_redraw_object(ob);
}
void fl_set_object_color(FL_OBJECT *ob,int col1,int col2)
/* Sets the color of the object */
{
if (ob == NULL)
{ fl_error("fl_set_object_color","Setting color of NULL object."); return;}
ob->col1 = col1;
ob->col2 = col2;
fl_redraw_object(ob);
}
void fl_set_object_label(FL_OBJECT *ob, const char *label)
/* sets the label of an object */
{
if (ob == NULL)
{ fl_error("fl_set_object_label","Setting label of NULL object."); return;}
if(label) /*TC */
ob->label = (char *) realloc(ob->label,strlen(label)+1);
strcpy(ob->label,label ? label:""); /*TC */
fl_redraw_object(ob);
}
void fl_set_object_lcol(FL_OBJECT *ob,int lcol)
/* sets the label color of an object */
{
if (ob == NULL)
{ fl_error("fl_set_object_lcol","Setting label color of NULL object."); return;}
ob->lcol = lcol;
fl_redraw_object(ob);
}
void fl_set_object_lsize(FL_OBJECT *ob,float lsize)
/* sets the label size of an object */
{
if (ob == NULL)
{ fl_error("fl_set_object_lsize","Setting label size of NULL object."); return;}
ob->lsize = lsize;
fl_redraw_object(ob);
}
void fl_set_object_lstyle(FL_OBJECT *ob,int lstyle)
/* sets the label style of an object */
{
if (ob == NULL)
{ fl_error("fl_set_object_lstyle","Setting label style of NULL object."); return;}
ob->lstyle = lstyle;
fl_redraw_object(ob);
}
void fl_set_object_align(FL_OBJECT *ob,int align)
/* sets the label alignment of an object */
{
if (ob == NULL)
{ fl_error("fl_set_object_align","Setting label alignment of NULL object."); return;}
ob->align = align;
fl_redraw_object(ob);
}
void fl_activate_object(FL_OBJECT *ob)
/* makes an object active if it was deactivated by fl_deactivate_object */
{
FL_OBJECT *obj = ob;
if (ob == NULL)
{ fl_error("fl_activate_object","Trying to activate NULL object."); return;}
if (ob->objclass == FL_BEGIN_GROUP)
while ( ob != NULL && ob->objclass != FL_END_GROUP)
{
if (ob->active < 0 ) ob->active = 1;
if (ob->input && ob->form->focusobj == NULL)
fl_set_object_focus(ob->form,ob);
ob = ob->next;
}
else
{
if (ob->active < 0 ) ob->active = 1;
if (ob->input && ob->form->focusobj == NULL)
fl_set_object_focus(ob->form,ob);
}
}
void fl_deactivate_object(FL_OBJECT *ob)
/* Deactivates an object */
{
FL_OBJECT *obj = ob;
if (ob == NULL)
{ fl_error("fl_deactive_object","Trying to deactive NULL object."); return;}
if (ob->objclass == FL_BEGIN_GROUP)
while ( ob != NULL && ob->objclass != FL_END_GROUP)
{
if (ob->active > 0 ) ob->active = -1;
if (ob == ob->form->focusobj )
fl_set_object_focus(ob->form,
fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
ob = ob->next;
}
else
{
if (ob->active > 0 ) ob->active = -1;
if (ob == ob->form->focusobj )
fl_set_object_focus(ob->form,
fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
}
}
void fl_show_object(FL_OBJECT *ob)
/* makes an object visible */
{
FL_OBJECT *obj = ob;
if (ob == NULL)
{ fl_error("fl_show_object","Trying to show NULL object."); return;}
if (ob->objclass == FL_BEGIN_GROUP)
while ( ob != NULL && ob->objclass != FL_END_GROUP)
{
ob->visible = 1;
if (ob->input && ob->form->focusobj == NULL)
fl_set_object_focus(ob->form,ob);
ob = ob->next;
}
else
{
ob->visible = 1;
if (ob->input && ob->form->focusobj == NULL)
fl_set_object_focus(ob->form,ob);
}
fl_redraw_object(obj);
}
void fl_hide_object(FL_OBJECT *ob)
/* makes an object invisible */
{
FL_OBJECT *obj = ob;
if (ob == NULL)
{ fl_error("fl_hide_object","Trying to hide NULL object."); return;}
if (ob->objclass == FL_BEGIN_GROUP)
while ( ob != NULL && ob->objclass != FL_END_GROUP)
{
ob->visible = 0;
if (ob == ob->form->focusobj )
fl_set_object_focus(ob->form,
fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
ob = ob->next;
}
else
{
ob->visible = 0;
if (ob == ob->form->focusobj )
fl_set_object_focus(ob->form,
fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
}
fl_redraw_form(obj->form);
}
void fl_set_object_shortcut(FL_OBJECT *obj, const char *str)
/* Sets the list of shortcuts for the object */
{
char sc[512];
int i=0, j=0, offset=0;
if (obj == NULL)
{ fl_error("fl_set_object_shortcut","Object is NULL."); return;}
while (str[i] != '\0')
{
if (str[i] == '#')
{
offset = 128;
}
else if (str[i] == '^')
{
i++;
if (str[i] >= 'A' && str[i] <= 'Z') sc[j++] = str[i]-'A'+1 + offset;
else if (str[i] >= 'a' && str[i] <= 'z') sc[j++] = str[i]-'a'+1 + offset;
else sc[j++] = str[i] + offset;
offset = 0;
}
else
{
sc[j++] = str[i] + offset;
offset = 0;
}
i++;
}
sc[j] = '\0';
obj->shortcut = (char *) realloc(obj->shortcut,strlen(sc)+1);
strcpy(obj->shortcut,sc);
}
void fl_set_object_focus(FL_FORM *form, FL_OBJECT *obj)
/* Sets the object in the form on which the input is focussed. */
{
if (form == NULL)
{ fl_error("fl_set_object_focus","Setting focus in NULL form."); return;}
if (obj == form->focusobj) return;
fl_handle_object_direct(form->focusobj,FL_UNFOCUS,0.0,0.0,0);
fl_handle_object_direct(obj,FL_FOCUS,0.0,0.0,0);
}
/*-----------------------------------------------------------------------
Searching in forms
-----------------------------------------------------------------------*/
FL_OBJECT *fl_find_object(FL_OBJECT *obj,int find,float mx,float my)
/* returns object in form starting at obj of type find */
{
while (obj != NULL)
{
if (obj->objclass != FL_BEGIN_GROUP && obj->objclass != FL_END_GROUP &&
obj->visible && obj->active > 0)
{
if (find == FL_FIND_INPUT && obj->input) return obj;
if (find == FL_FIND_AUTOMATIC && obj->automatic) return obj;
if (find == FL_FIND_MOUSE && mx >= obj->x && mx <= obj->x+obj->w &&
my >= obj->y && my <= obj->y + obj->h) return obj;
}
obj = obj->next;
}
return NULL;
}
FL_OBJECT *fl_find_first(FL_FORM *form,int find,float mx,float my)
/* returns the first object of type find */
{
return ( fl_find_object(form->first,find,mx,my) );
}
FL_OBJECT *fl_find_last(FL_FORM *form,int find,float mx,float my)
/* returns the last object of the type find */
{
FL_OBJECT *last, *obj;
last = obj = fl_find_first(form,find,mx,my);
while (obj != NULL)
{ last = obj; obj = fl_find_object(obj->next,find,mx,my); }
return last;
}
/*-----------------------------------------------------------------------
Drawing Routines.
-----------------------------------------------------------------------*/
static void redraw_marked(FL_FORM *form)
/* Redraws all marked objects and reduces the mark */
{
FL_OBJECT *ob;
if (!form->visible || form->frozen > 0) return;
fl_save_user_window();
fl_set_forms_window(form);
ob = form->first;
while (ob != NULL)
{
if (ob->visible && ob->redraw-- > 0) fl_handle_object(ob,FL_DRAW,0.,0.,0);
ob = ob->next;
}
if (form->doublebuf) swapbuffers();
fl_restore_user_window();
}
void fl_redraw_object(FL_OBJECT *obj)
/* The actual drawing routine seen by the user */
{
FL_OBJECT *ob;
int drawnumb;
if (obj == NULL)
{ fl_error("fl_redraw_object","Trying to draw NULL object."); return;}
if (obj->form == NULL) return;
if (obj->form->doublebuf) drawnumb = 2; else drawnumb = 1;
if (obj->objclass == FL_BEGIN_GROUP)
{
ob = obj;
while ( (ob = ob->next) != NULL && ob->objclass != FL_END_GROUP )
ob->redraw = drawnumb;
}
else
obj->redraw = drawnumb;
redraw_marked(obj->form);
}
void fl_redraw_form(FL_FORM *form)
/* Draws a form */
{
FL_OBJECT *ob;
int drawnumb;
if (form == NULL)
{ fl_error("fl_redraw_form","Drawing NULL form."); return;}
if (form->doublebuf) drawnumb = 2; else drawnumb = 1;
ob = form->first;
while ( ob != NULL )
{ ob->redraw = drawnumb; ob = ob->next; }
redraw_marked(form);
}
void fl_freeze_object(FL_OBJECT *obj)
/* Disables drawing of object */
/* TO BE REMOVED */
{
fprintf(stderr, "fl_freeze_object() is obsolete. Use fl_freeze_form() instead\n");
if (obj == NULL)
{ fl_error("fl_freeze_object","Freezing NULL object."); return;}
fl_freeze_form(obj->form);
}
void fl_unfreeze_object(FL_OBJECT *obj)
/* Enable drawing of object */
/* TO BE REMOVED */
{
fprintf(stderr, "fl_unfreeze_object() is obsolete. Use fl_unfreeze_form() instead\n");
if (obj == NULL)
{ fl_error("fl_freeze_object","Unfreezing NULL object."); return;}
fl_unfreeze_form(obj->form);
}
void fl_freeze_form(FL_FORM *form)
/* Disables drawing of form */
{
if (form == NULL)
{ fl_error("fl_freeze_form","Freezing NULL form."); return;}
form->frozen++;
}
void fl_unfreeze_form(FL_FORM *form)
/* Enable drawing of form */
{
if (form == NULL)
{ fl_error("fl_unfreeze_form","Unfreezing NULL form."); return;}
if (form->frozen == 0)
{ fl_error("fl_unfreeze_form","Unfreezing non-frozen form."); return;}
form->frozen--;
if (form->frozen == 0) redraw_marked(form);
}
/*-----------------------------------------------------------------------
Handling Routines.
-----------------------------------------------------------------------*/
static int fl_handle_it(FL_OBJECT *obj,int event,float mx,float my,char key)
/* handles an event for an object */
{
if (obj == NULL) return 0;
if (obj->objclass == FL_BEGIN_GROUP || obj->objclass ==FL_END_GROUP) return 0;
if (obj->handle == NULL) return 0;
switch (event)
{
case FL_ENTER: obj->belowmouse = 1; break;
case FL_LEAVE: obj->belowmouse = 0; break;
case FL_PUSH: obj->pushed = 1; break;
case FL_RELEASE: if (! obj->radio) obj->pushed = 0; break;
case FL_FOCUS: obj->form->focusobj = obj; obj->focus = 1; break;
case FL_UNFOCUS: obj->form->focusobj = NULL; obj->focus = 0; break;
}
return (*(obj->handle))(obj,event,mx,my,key);
}
void fl_handle_object(FL_OBJECT *obj,int event,float mx,float my,char key)
/* handle and store if successfull */
{ if (fl_handle_it(obj,event,mx,my,key)) fl_object_qenter(obj); }
int fl_handle_object_direct(FL_OBJECT *obj,int event,float mx,float my,char key)
/* handle but returns whether successfull */
{ return fl_handle_it(obj,event,mx,my,key); }
/* TC: added to minimize redraw of forms in single buffer mode*/
void fl_hide_object_only(FL_OBJECT *ob)
{
long owin = winget();
int cols;
if(fl_doublebuf) {fl_hide_object(ob); return; }
if (ob == NULL)
{ fl_error("fl_hide_object_only","Trying to hide NULL object.");
return;}
if(!ob->visible || !ob->form->visible) {
fl_hide_object(ob);
return ;
}
/* here, difficult to guess what the form bk color is */
if(ob->form->first->next->objclass == FL_BOX &&
ob->form->first->next->type != FL_NO_BOX )
cols = ob->form->first->next->col1;
else
cols = ob->form->first->col1;
winset(ob->form->window);
fl_color(cols);
rectf(ob->x-0.2, ob->y-0.2, ob->x+ob->w-0.8,ob->y+ob->h-0.8);
fl_drw_text_beside(ob->align, ob->x, ob->y, ob->w, ob->h,
cols, ob->lsize, ob->lstyle, ob->label);
ob->visible = 0;
if(owin > 0) winset(owin);
}